home *** CD-ROM | disk | FTP | other *** search
- //
- // Finger Version 3.1, a Windows Sockets Finger Client
- //
- // Copyright 1992, 1993 Network Research Corporation
- //
- // Permission to use, modify, and distribute this software and its
- // documentation for any purpose and without fee is hereby granted, provided
- // that the above copyright notice appears in all copies and that both
- // that copyright notice and this permission notice appear in supporting
- // documentation. NRC makes no claims as to the suitability of this software
- // for any purpose.
- //
- // Module FINGER provides the user interface for the finger client, and
- // depends on NETWRK for TCP/IP network services, and upon DSPLIST
- // retrieve and dispose of "display lists". The display list represents
- // the remote finger server's return in a form suitable for scrolling text
- // display. FINGER prompts the user for a host name (or internet address),
- // invokes NETWRK to finger the specified host, and paints the window
- // client area with the returned display list. FINGER uses a view
- // (a logical window onto a portion of the display list) to render
- // that portion of the list which is currently visable.
- //
- // 02/12/92 Lee Murach Created.
- // 06/19/92 Mark Towfiq Adapted to Windows Socket draft rev 1.0.
- // 09/25/92 Ian Merritt Adapted for Windows Sockets 1.0B compatability.
- // 10/20/92 Lee Murach Restructured (Ray Duncan-ized) & added scrollbars.
- // 12/02/92 Lee Murach Split FingerHost() into FingerStart() &
- // FingerFinish(), for NETWORK_ module interface.
- // 03/25/93 Lee Murach Added per-user finger support.
- //
-
- #include <windows.h>
- #include <stdlib.h>
- #include <string.h>
- #include <winsock.h>
- #include "finger.h"
-
- #define MAXTEXT 132
- #define THUMBPOS LOWORD(lParam) // Win 16
-
- typedef struct // associates an error code with text
- {
- UINT err;
- char *sztext;
- } ERRENTRY;
-
- int APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
- LONG FAR APIENTRY FrameWndProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- BOOL APIENTRY HostDlgProc(HWND hDlg, UINT wMsg, UINT wParam, LONG lParam);
- BOOL FAR APIENTRY AboutDlgProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- BOOL InitInstance(HANDLE hInstance, int nCmdShow);
- BOOL InitApp(HANDLE hInstance);
- LONG DoPaint(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoSize(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoCommand(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoDestroy(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoMouseMove(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoMenuHost(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoVScroll(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoActivate(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoClose(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoMenuExit(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- LONG DoMenuAbout(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam);
- VOID Repaint(VOID);
- VOID PosView(int nlines);
- VOID ReportWSError(UINT Err);
- VOID RelScroll(HWND hWnd, int nlines);
- VOID SetWinCaption(VOID);
- VOID SetScroll(VOID);
- VOID ReportWSError(UINT Err);
-
- char szHostName[MAXHOST+1] = "";// name of host to finger
- char szUser[MAXUSER+1] = ""; // query for this user id (can be null)
- char szAppName[] = "Finger"; // application's name
- LINEITEM *pLineItems = 0; // ptr to display list LINEITEMS
- int nLineItems = 0; // number of items in display list
- LINEITEM *pTopLine; // pts to topmost displayable LINEITEM
- int nTopLine = 0; // line number of topmost displayed line
- int nClientLines; // # of text lines in view
- int CharY; // pixel character height
- HWND hFrame; // finger main window handle
- HMENU hMenu; // main window menu handle
- HANDLE hInst; // this instance of finger
- HCURSOR hCursor; // current cursor (either wait or normal)
- WSADATA WSAData; // windows sockets info return
-
- DECODEWORD frameMsgs[] = // windows messages & handlers
- {
- WM_ACTIVATE, DoActivate,
- WM_CLOSE, DoClose,
- WM_COMMAND, DoCommand,
- WM_DESTROY, DoDestroy,
- WM_MOUSEMOVE, DoMouseMove,
- WM_PAINT, DoPaint,
- WM_SIZE, DoSize,
- WM_VSCROLL, DoVScroll,
- WM_KEYDOWN, DoVScroll,
- };
-
- DECODEWORD menuItems[] = // menu items & associated handlers
- {
- IDM_HOST, DoMenuHost,
- IDM_EXIT, DoMenuExit,
- IDM_ABOUT, DoMenuAbout,
- };
-
- ERRENTRY wsErrs[] = // error text for windows sockets errors
- {
- WSAVERNOTSUPPORTED, "This version of Windows Sockets is not supported",
- WSASYSNOTREADY, "Windows Sockets is not present or is not responding",
- };
-
- ERRENTRY finErrs[] = // finger specific error text
- {
- FE_NOPORT, "Cannot locate port for finger service",
- FE_NOHOST, "Unrecognized host name",
- FE_NOSOCK, "Cannot obtain socket for connection",
- FE_NOCONN, "Cannot connect to remote server",
- FE_NOSEND, "Cannot send query to remote server",
- FE_NORECV, "Error occurred during retrieval"
- };
-
- //
- // WinMain -- windows calls this to start the application.
- //
- int APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow)
- {
- MSG msg; // holds current message
- int err;
-
- hInst = hInstance; // save our instance handle
-
- if (!hPrevInstance) // if first instance,
- if (!InitApp(hInstance)) // register window classes
- {
- MessageBox(hFrame, "Can't initialize Finger", szAppName,
- MB_ICONSTOP | MB_OK);
- return(FALSE);
- }
-
- if (!InitInstance(hInstance, nCmdShow)) // per instance initialization &
- { // window creation
- MessageBox(hFrame, "Can't initialize Finger", szAppName,
- MB_ICONSTOP | MB_OK);
- return(FALSE);
- }
-
- if (err = WSAStartup(WSVERSION, &WSAData))// register task with
- { // winsock tcp/ip API
- ReportWSError(err);
- DestroyWindow(hFrame); // kill application window &
- } // signal app exit
-
- while (GetMessage(&msg, NULL, 0, 0)) // loop til WM_QUIT
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- WSACleanup(); // disconnect from winsock
- return msg.wParam; // return to windows
- }
-
- //
- // InitApp -- initialization for all instances of application.
- // Registers main window class.
- //
- BOOL InitApp(HANDLE hInstance)
- {
- WNDCLASS wndclass;
-
- InitNetApp(); // initializes (per application) network module
-
- wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
- wndclass.lpfnWndProc = FrameWndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(hInst, "FingerIcon");
- wndclass.hCursor = NULL;
- wndclass.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
- wndclass.lpszMenuName = "FingerMenu";
- wndclass.lpszClassName = szAppName;
-
- return(RegisterClass(&wndclass));
- }
-
- //
- // InitInstance -- initializes this instance of app, and creates windows.
- //
- BOOL InitInstance(HANDLE hInstance, int nCmdShow)
- {
- HDC hdc; // handle of device context
- TEXTMETRIC tm; // contains font dimensions
- RECT rect; // outer dimensions of window
-
- hFrame = CreateWindow( szAppName, szAppName,
- WS_OVERLAPPEDWINDOW | WS_VSCROLL,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, hInstance, NULL);
-
- if (!hFrame)
- return(FALSE);
-
- hCursor = LoadCursor(NULL, IDC_ARROW);
- hMenu = GetMenu(hFrame);
-
- InitNetInst(hFrame); // initialize (per instance) the network module
-
- // finger servers assume a fixed font
- hdc = GetDC(hFrame);
- SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
- GetTextMetrics(hdc, &tm);
- CharY = tm.tmHeight + tm.tmExternalLeading;
- ReleaseDC(hFrame, hdc);
-
- // set initial window width & height to 50x10 chars
- GetWindowRect(hFrame, &rect);
- MoveWindow( hFrame, rect.left, rect.top,
- 65 * tm.tmAveCharWidth + GetSystemMetrics(SM_CXVSCROLL),
- 10 * CharY + GetSystemMetrics(SM_CYCAPTION) +
- GetSystemMetrics(SM_CYMENU), FALSE);
-
- ShowWindow(hFrame, nCmdShow);
- UpdateWindow(hFrame);
-
- return(TRUE);
- }
-
- //
- // FrameWndProc -- callback function for application frame (main) window.
- // Decodes message and routes to appropriate message handler. If no handler
- // found, calls DefWindowProc.
- //
- LONG FAR APIENTRY FrameWndProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- int i;
-
- for (i = 0; i < dim(frameMsgs); i++)
- {
- if (wMsg == frameMsgs[i].Code)
- return(*frameMsgs[i].Fxn)(hWnd, wMsg, wParam, lParam);
- }
-
- return(DefWindowProc(hWnd, wMsg, wParam, lParam));
- }
-
- //
- // DoCommand -- demultiplexes WM_COMMAND messages resulting from menu
- // selections, and routes to corresponding menu item handler. Sends back
- // any unrecognized messages to windows.
- //
- LONG DoCommand(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- int i;
-
- for (i = 0; i < dim(menuItems); i++)
- {
- if (wParam == menuItems[i].Code)
- return(*menuItems[i].Fxn)(hWnd, wMsg, wParam, lParam);
- }
-
- return(DefWindowProc(hWnd, wMsg, wParam, lParam));
- }
-
- //
- // DoMenuHost -- handles the "Host..." menu item. We prompt for a
- // Domain Name System (DNS) host name, or a "dotted IP address" (e.g.,
- // 129.216.202.5). The function invokes NETWRK_ module FingerStart()
- // routine to initiate a conversation with the finger server on the
- // remote host. NETWRK_, in turn, calls FingerFinish() to signal
- // completion. Note that the "Host..." menu item is disabled while the
- // finger operation is in progress. This prevents the user from
- // starting yet another finger before the first is finished; Finger is
- // not designed to process simultaneous requests.
- //
- LONG DoMenuHost(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- FARPROC lpfnProc;
- int ret;
-
- // prompt for the host's domain name or ip address
-
- lpfnProc = MakeProcInstance(HostDlgProc, hInst);
- ret = DialogBox(hInst, szAppName, hWnd, lpfnProc);
- FreeProcInstance(lpfnProc);
-
- if (ret == IDOK && szHostName[0])
- {
- SetCursor(hCursor = LoadCursor(NULL, IDC_WAIT));
- EnableMenuItem(hMenu, IDM_HOST, MF_GRAYED);
- FingerStart();
- }
-
- return(FALSE);
- }
-
- //
- // FingerFinish -- invoked when the finger operation is complete,
- // this function updates the display list & repaints the frame window
- // client area if the operation was successful.
- //
- VOID FingerFinish(UINT Err)
- {
- if (!Err)
- {
- FreeLineList(pLineItems); // dispose old display
- GetDisplayList(&pLineItems, &nLineItems); // list and get new one
-
- SetWinCaption(); // set win title to host name
- PosView(0); // position view to top
- SetScroll(); // rescale (or delete)
- Repaint(); // scrollbar & force a repaint
- }
-
- EnableMenuItem(hMenu, IDM_HOST, MF_ENABLED);
- SetCursor(hCursor = LoadCursor(NULL, IDC_ARROW));
- }
-
- //
- // DoMenuExit -- allows close via menu item. Same as sys menu close.
- //
- LONG DoMenuExit(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- SendMessage(hWnd, WM_CLOSE, 0, 0);
- return(FALSE);
- }
-
- //
- // DoMenuAbout -- respond to "About..." menu selection by invoking the
- // "About" dialog box.
- //
- LONG DoMenuAbout(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- WNDPROC lpProcAbout;
-
- lpProcAbout = MakeProcInstance((WNDPROC)AboutDlgProc, hInst);
- DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
- FreeProcInstance(lpProcAbout);
-
- return(FALSE);
- }
-
- //
- // DoDestroy -- posts a WM_QUIT message to the task's win queue, which
- // causes the main translate & dispatch loop to exit, and the app to
- // terminate.
- //
- LONG DoDestroy(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- PostQuitMessage(0);
- return(FALSE);
- }
-
- //
- // DoClose -- cleans up display list & tells windows to deallocate
- // our window.
- //
- LONG DoClose(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- FreeLineList(pLineItems);
- DestroyWindow(hWnd);
-
- return(FALSE);
- }
-
- //
- // DoActivate -- grabs the keyboard focus whenever our deminimized window
- // is activated. This is so we can respond to VK_HOME, VK_END, etc.
- // virtual keys for scrolling. HIWORD(lParam) is TRUE for minimized, while
- // LOWORD(wParam) is FALSE for activation message.
- //
- LONG DoActivate(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- if (!HIWORD(lParam) && LOWORD(wParam))
- SetFocus(hFrame);
-
- return FALSE;
- }
-
- //
- // DoMouseMove -- resets the cursor back to the current cursor (either
- // a wait, or normal cursor) because Windows will otherwise redraw it
- // using the window's class.
- //
- LONG DoMouseMove(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- SetCursor(hCursor);
- return(FALSE);
- }
-
- //
- // PosView -- repositions the view relative to the top of the display list.
- // The view is a logical "window" onto the display list. The frame window's
- // client area is painted with the view's contents.
- //
- VOID PosView(int nlines)
- {
- LINEITEM *pline;
- int i;
-
- pline = pLineItems; // root of LINEITEM list
-
- for (i = 0; i < nlines; i++)
- {
- if (!pline)
- break;
- else
- pline = pline->next;
- }
-
- pTopLine = pline; // ptr to LINEITEM in topmost view line
- nTopLine =+ nlines; // offset of topmost view line
- }
-
- //
- // DoPaint -- Paint the client area with the contents of the view.
- //
- LONG DoPaint(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- HDC hdc; // scratch device context
- PAINTSTRUCT ps; // scratch paint structure
- LINEITEM *pline; // pts to topmost displayable LINEITEM
- int i;
-
- pline = pTopLine;
- hdc = BeginPaint(hWnd, &ps);
-
- for (i = 0; i <= nClientLines; i++)
- {
- if (pline)
- {
- TextOut(hdc, 0, i * CharY, pline->sztext, pline->len);
- pline = pline->next;
- }
- else
- break;
- }
-
- EndPaint(hWnd, &ps);
- return(FALSE);
- }
-
- //
- // Repaint -- force refresh of client window.
- //
- VOID Repaint(VOID)
- {
- InvalidateRect(hFrame, NULL, TRUE);
- }
-
- //
- // SetScroll -- sets the vertical scroll range to the length of the display
- // list. The Scrollbar disappears when the list fits within the view.
- //
- VOID SetScroll(VOID)
- {
- if (nLineItems > nClientLines)
- SetScrollRange(hFrame, SB_VERT, 0, nLineItems - nClientLines, FALSE);
- else
- SetScrollRange(hFrame, SB_VERT, 0, 0, FALSE);
-
- SetScrollPos(hFrame, SB_VERT, nTopLine, TRUE);
- }
-
- // number of lines below the bottom of the view.
- #define NLINESBELOW (nLineItems - nTopLine - nClientLines)
-
- //
- // DoVScroll -- process WM_VSCROLL & WM_KEYDOWN for main window.
- //
- LONG DoVScroll(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- switch (LOWORD(wParam))
- {
- case VK_HOME:
- case SB_TOP:
- if (nTopLine > 0)
- RelScroll(hWnd, -nTopLine);
- break;
-
- case VK_END:
- case SB_BOTTOM:
- if (NLINESBELOW)
- RelScroll(hWnd, NLINESBELOW);
- break;
-
- case VK_PRIOR:
- case SB_PAGEUP:
- if (nTopLine > 0)
- RelScroll(hWnd, max(-nClientLines, -nTopLine));
- break;
-
- case VK_NEXT:
- case SB_PAGEDOWN:
- if (NLINESBELOW)
- RelScroll(hWnd, min(nClientLines, NLINESBELOW));
- break;
-
- case VK_UP:
- case SB_LINEUP:
- if (nTopLine > 0)
- RelScroll(hWnd, -1);
- break;
-
- case VK_DOWN:
- case SB_LINEDOWN:
- if (NLINESBELOW)
- RelScroll(hWnd, 1);
- break;
-
- case SB_THUMBTRACK:
- RelScroll(hWnd, THUMBPOS - nTopLine);
- break;
- }
-
- SetScrollPos(hFrame, SB_VERT, nTopLine, TRUE);
- return(FALSE);
- }
-
- //
- // RelScroll -- scroll up/down nlines from present position
- //
- VOID RelScroll(HWND hWnd, int nlines)
- {
- PosView(nTopLine + nlines);
- ScrollWindow(hWnd, 0, -nlines * CharY, NULL, NULL);
- UpdateWindow(hWnd);
- }
-
- //
- // DoSize -- respond to WM_SIZE by recalculating the number of text lines
- // in the main window's client area.
- //
- LONG DoSize(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- nClientLines = HIWORD(lParam) / CharY;
- PosView(0);
- SetScroll();
-
- return(FALSE);
- }
-
- //
- // SetWinCaption -- set the frame window caption according to last
- // host fingered.
- //
- VOID SetWinCaption(VOID)
- {
- char szcaption[80];
-
- strcpy(szcaption, szAppName);
- strcat(szcaption, " - ");
- strcat(szcaption, szHostName);
-
- SetWindowText(hFrame, szcaption);
- }
-
- //
- // ReportWSError -- prompt user with a windows sockets error message.
- //
- VOID ReportWSError(UINT Err)
- {
- int i;
- char szerr[40];
-
- for (i = 0; i < dim(wsErrs); i++)
- {
- if (Err == wsErrs[i].err)
- {
- MessageBox(hFrame, wsErrs[i].sztext, szAppName,
- MB_ICONSTOP | MB_OK);
- return;
- }
- }
-
- wsprintf(szerr, "Windows Sockets reports error %04x", Err);
- MessageBox(hFrame, szerr, szAppName, MB_ICONSTOP | MB_OK);
- }
-
- //
- // ReportFingerErr -- prompt user with a finger specific error
- //
- VOID ReportFingerErr(UINT Err)
- {
- int i;
-
- for (i = 0; i < dim(finErrs); i++)
- {
- if (Err == finErrs[i].err)
- {
- MessageBox(hFrame, finErrs[i].sztext, szAppName,
- MB_ICONSTOP | MB_OK);
- return;
- }
- }
-
- MessageBox(hFrame, "Unrecognized finger error", szAppName,
- MB_ICONSTOP | MB_OK);
- }
-
- //
- // HostDlgProc -- dialog box proc for "host dialog".
- // This box queries user for a host name in response to the user's
- // selection of the "Host..." main menu item.
- //
- BOOL APIENTRY HostDlgProc(HWND hDlg, UINT wMsg, UINT wParam, LONG lParam)
- {
- switch(wMsg)
- {
- case WM_INITDIALOG:
- SetDlgItemText(hDlg, IDC_HOSTNAME, szHostName);
- SetDlgItemText(hDlg, IDC_USER, szUser);
- return TRUE;
-
- case WM_COMMAND:
- switch(wParam)
- {
- case IDOK:
- GetDlgItemText(hDlg, IDC_HOSTNAME, szHostName, MAXHOST);
- GetDlgItemText(hDlg, IDC_USER, szUser, MAXUSER);
- EndDialog(hDlg, IDOK);
- return TRUE;
-
- case IDCANCEL:
- EndDialog(hDlg, IDCANCEL);
- return TRUE;
- }
- break;
- }
-
- return FALSE;
- }
-
- //
- // AboutDlgProc -- callback for the "About" dialog box
- //
- BOOL FAR APIENTRY AboutDlgProc(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
- {
- if ((wMsg == WM_COMMAND) && (wParam == IDOK)) // dismiss dialog if OK
- EndDialog(hWnd, 0);
-
- return(FALSE); // otherwise just sit there
- }
-